import { type FC, useRef } from 'react';
import { View } from 'react-native';
import Animated from 'react-native-reanimated';
import { useUpdateEffect, useMemoizedFn, useSafeState, useUnmount } from 'ahooks';
import { useContentStyle, useHeight, useAnimateStyle } from './hooks';

import Mask from './mask';
import type { DialogProps } from './types';
import { SCREEN_WIDTH } from '@/utils/resize';
import styles from './styles';

const DialogContent: FC<DialogProps> = (props) => {
  const {
    open = false,
    type = 'bottom',
    duration = 250,
    statusBarStyle,
    centerCloseZoom,
    maskClosable = true
  } = props;

  const [height] = useHeight();
  const timer = useRef<NodeJS.Timeout>();
  const [rootShow, setRootShow] = useSafeState(open);
  const [contentShow, setContentShow] = useSafeState(open);
  const contentStyles = useContentStyle(type);

  const animateStyle = useAnimateStyle({
    type,
    duration,
    centerCloseZoom,
    open: contentShow
  });

  // 清空时间
  const clearTimer = useMemoizedFn(() => {
    clearTimeout(timer.current);
  });

  // 隐藏根元素
  const closeRoot = useMemoizedFn(() => {
    setRootShow(false);
    props.afterClose?.();
  });

  // 打开弹窗
  const openModal = useMemoizedFn(() => {
    setRootShow(true);
    setTimeout(() => setContentShow(true), 10);
  });

  // 关闭弹窗
  const closeModal = useMemoizedFn(() => {
    setContentShow(false);
    timer.current = setTimeout(closeRoot, duration);
  });

  const updateState = useMemoizedFn(() => {
    clearTimer();
    if (open) {
      openModal();
    } else {
      closeModal();
    }
  });

  useUnmount(clearTimer);
  useUpdateEffect(updateState, [open]);

  const wrapperStyles = [
    styles.modal,
    { height },
    styles[type],
    !rootShow && styles.hidden
  ];

  return (
    <View style={wrapperStyles}>
      <Mask
        height={height}
        show={contentShow}
        duration={duration}
        onClose={props.onClose}
        maskClosable={maskClosable}
        statusBarStyle={statusBarStyle}
      />
      <Animated.View
        style={[
          styles.content,
          animateStyle,
          contentStyles
        ]}
      >
        {props.children?.({
          height: height,
          width: SCREEN_WIDTH
        })}
      </Animated.View>
    </View>
  );
}

export default DialogContent;